package cn.wolfcode.wolf2w.interceptor;

import cn.wolfcode.wolf2w.annotation.RequireLogin;
import cn.wolfcode.wolf2w.cache.service.IUserInfoRedisService;
import cn.wolfcode.wolf2w.domain.UserInfo;
import cn.wolfcode.wolf2w.util.JsonResult;
import com.alibaba.fastjson.JSON;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * 用户登录检查
 */
public class CheckLoginInterceptor implements HandlerInterceptor{

    @Autowired
    private IUserInfoRedisService userInfoRedisService;

    //实现登录拦截
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response,
                             Object handler)
            throws Exception {
        //排除跨域问题
        //HandlerMethod 代指: 动态请求
        //HandlerMethod 请求映射方法在springmvc封装对象
        /**
         *  1:spring容器启动是会解析所有@RequestMapping 标签
         *  将解析到所有请求映射方法相关信息(路径, 方法名, 方法参数 注解...)
         *  封装成HandlerMethod对象
         *  2: 将步骤1得到所有请求映射方法对象, 封装到一个类似map数据
         *    key值是映射路径  value值就是HandlerMethod对象
         *
         *    Map<String, HandlerMethod> map
         *
         *    key                   value
         *    /users/currentUser    currentUser映射方法对应:HandlerMethod对象
         *    /users/login          login映射方法对应:HandlerMethod对象
         *
         *  3:当浏览器发起请求时, springmvc前端控制器会解析请求得到路径
         *    http://localhost:8080/users/currentUser
         *
         *    url(key) : /users/currentUser
         *    HandlerMethod value = map.get("/users/currentUser")
         *
         *   通过一系列操作得到 value对象, 然后传入到interceptor拦截器
         *    preHandler方法中(作为参数传入)
         */
        if(!(handler instanceof HandlerMethod)){
            return true;
        }
        //1:判断当前请求方法上是否有注解@RequireLogin
        HandlerMethod hm = (HandlerMethod) handler;

        String token = request.getHeader("token");
        UserInfo user = userInfoRedisService.getUserByToken(token);

        //2:如果有进行登录校验
        if(hm.hasMethodAnnotation(RequireLogin.class)){
            if(user == null){
                //没有登录
                response.setContentType("application/json; charset=utf-8"); //json数据中文转码
                response.getWriter().write(JSON.toJSONString(JsonResult.noLogin()));
                return false;
            }
        }
        //3:如果没有放行
        return true;
    }
}
